/*
 * =====================================================================================
 *       Filename:  simq.c
 *    Description:  文件同步传输服务主程序
 *        Version:  1.0
 *        Created:  2015-01-07 15:40
 *         Author:  mien, m@p58.net
 * =====================================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <netdb.h>
#include <signal.h>

#include "net.h"
#include "http/http.h"
#include "config.h"
#include "factory.h"

#define DEFAULT_CONFIG_FILE "conf/simq.conf"

static void daemonize() {
    int fd;

    if (fork() != 0) exit(0);
    setsid();

    if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
        dup2(fd, STDIN_FILENO);
        dup2(fd, STDOUT_FILENO);
        dup2(fd, STDERR_FILENO);
        if (fd > STDERR_FILENO) close(fd);
    }
}

static void sigShutdownHandler(int sig) {
    char *msg;

    switch (sig) {
    case SIGINT:
        msg = "Received SIGINT scheduling shutdown...";
        break;
    case SIGTERM:
        msg = "Received SIGTERM scheduling shutdown...";
        break;
    default:
        msg = "Received shutdown signal, scheduling shutdown...";
    };
    printf(msg);

    factoryDump();
    factoryFree();

    cmdFree();
    freeConfig();

    exit(1);
}

void setupSignalHandlers(void) {
    struct sigaction act;

    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    act.sa_handler = sigShutdownHandler;
    sigaction(SIGTERM, &act, NULL);
    sigaction(SIGINT, &act, NULL);
}

int main(int argc, char* argv[])
{
    loadConfig(argc == 2 ? argv[1] : DEFAULT_CONFIG_FILE);

    setUidGid();

    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    setupSignalHandlers();

    if (!strcmp(getConfig("server_daemonize"), "yes"))
        daemonize();

    cmdInit();

    factoryCreate();
    factoryRestore(
        getConfig("queue_data_dir"));

    tcpListen(
        getConfig("server_host"),
        getConfig("server_port"),
        httpHandle);
    
    return EXIT_SUCCESS;
}
